package com.hongdee.rbac.roledata.service.impl;

import com.hongdee.rbac.roledata.dao.ITBcRoleDataDao;
import com.hongdee.rbac.roledata.entity.TBcRoleData;
import com.hongdee.rbac.roledata.entity.TBcRoleDataOrg;
import com.hongdee.rbac.roledata.service.ITBcRoleDataService;
import com.hongdee.rbac.user.entity.TBcRoleUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.hongdee.rbac.Constant.*;

/**
 * 名  称:ParamDefServiceImpl
 * 类  型: class
 * 描  述: 用一句话描述类的作用
 * 路  径:com.hongdee.base.rbac.service.impl
 * 作  者:zhuhongchao
 * 日  期:2017/1/20 12:24
 */

@Service
public class TBcRoleDataServiceImpl implements ITBcRoleDataService {


    private String tabName = "T_BC_ROLE_DATA";

    @Autowired
    private ITBcRoleDataDao tBcRoleDataDao;
    /*
     checkedOrgMap 存储已选中的组织，或人
     */
    private Map<String, String> checkedOrgMap;

    /**
     * 方法名称: page
     * 方法描述: 分页查询
     * 参数名称: String start 起始行数
     * 参数名称: String limit 分页大小
     * 参数名称: String sql sql语句
     * 参数名称: String roleName 查询所需参数
     * 返回内容: Map
     * 异常说明: Exception
     * 创建用户:术洪超
     * 创建时间:
     * 修改用户:术洪超
     * 修改时间:2017/2/8
     * 修改内容:注释内容
     */
    @Override
    public Map page(String start, String limit, String uid, String roleName) throws Exception {

        String sqlStr = "select distinct r.* from t_bc_role_data r ,t_bc_role_user ru where r.id = ru.r_id "
                + " and   ru.u_id = ? and r.role_name like ?  order by r.create_time desc,disp_order asc ";

        return tBcRoleDataDao.page(sqlStr, new Object[]{uid, "%" + roleName + "%"}, start, limit);

    }

    /**
     * 方法名称: info
     * 方法描述: 详情查询
     * 参数名称：String id 主键id
     * 返回内容: Map
     * 异常说明: Exception
     * 创建用户:术洪超
     * 创建时间:
     * 修改用户:术洪超
     * 修改时间:2017/2/8
     * 修改内容:注释内容
     */
    @Override
    public Map info(String id) throws Exception {
        if (StringUtils.isEmpty(id)) {
            throw new Exception("请选择资源");
        }
        String sql = "select * from " + tabName + " where id = ? ";
        return this.tBcRoleDataDao.info(sql, new Object[]{id});
    }

    /**
     * 方法名称: saveOrUpdate
     * 方法描述:  保存或更新实体，通过主键判断
     *
     * @param data TBcRoleData data 要保存的变更历史记录实体
     * @param uid  当前用户
     * @return TBcRoleData 保存后的历史记录实体
     * @throws : Exception
     *           创建用户:术洪超
     *           创建时间:
     *           修改用户:术洪超
     *           修改时间:2017/2/8
     *           修改内容:注释内容
     */
    @Override
    public TBcRoleData saveOrUpdate(TBcRoleData data, String uid) throws Exception {
        if (null == data.getId()) {
            /**
             * 新增时判断当前用户是否是超管，如果是超管，则将该角色分配给超管，
             * 否则除超管外，还需分配给当前创建用户
             */
            this.tBcRoleDataDao.saveOrUpdate(data);
            List<Object> ls = new ArrayList();

            //保存关联关系
            TBcRoleUser tr = new TBcRoleUser();
            tr.setId(null);
            tr.setrId(data.getId());
            tr.setuId(SUPER_ID);
            tr.setType(DATA_ROLE);
            ls.add(tr);
            if (!SUPER_ID.equals(uid)) {
                TBcRoleUser tu = new TBcRoleUser();
                tu.setrId(data.getId());
                tu.setuId(uid);
                tu.setType(DATA_ROLE);
                tu.setId(null);
                ls.add(tu);
            }
            this.tBcRoleDataDao.saveOrUpdateList(ls);
        } else {
            //编辑
            this.tBcRoleDataDao.saveOrUpdate(data);
        }
        return data;
    }


    /**
     * 方法名称: update
     * 方法描述: 修改品牌状态
     * 参数名称: String id 主键id
     * 参数名称: String status 状态
     * 返回内容:
     * 异常说明:Exception
     * 创建用户:术洪超
     * 创建时间:
     * 修改用户:术洪超
     * 修改时间:2017/2/8
     * 修改内容:注释内容
     */
    @Override
    public void update(String id, String status) throws Exception {
        if (StringUtils.isEmpty(id)) {
            throw new Exception("请选择数据角色");
        }
        String hql = "update TBcRoleData set status = :status where id = :id ";
        Map roledata = new HashMap();
        roledata.put("id", id);
        roledata.put("status", status);
        this.tBcRoleDataDao.update(hql, roledata);
    }

    /**
     * 方法名称: ref
     * 方法描述: 查询数据角色关联
     * 参数名称: String sqlStr sql语句
     * 返回内容: Object... params 查询所需参数
     * 异常说明: Exception
     * 创建用户: 术洪超
     * 创建时间:
     * 修改用户:术洪超
     * 修改时间:2017/2/8
     * 修改内容:注释内容
     */
    @Override
    public List<String> ref(String id, String roleType) throws Exception {
        String sqlStr = " select org_id,user_id from t_bc_role_data_org where role_type= ? and role_id= ? ";
        List<Map<String, Object>> orgList = this.tBcRoleDataDao.list(sqlStr, roleType, id);
        /**
         * refList 存储已分配的组织或用户 ID
         */
        List refList = new ArrayList();
        if (roleType.equals(DEPT_ROLE)) {
            for (Map map : orgList) {
                //用户 ID 当做主键
                refList.add(String.valueOf(map.get("orgId")));
            }
            return refList;
        } else {
            //
            for (Map map : orgList) {
                //用户 ID 当做主键
                refList.add(String.valueOf(map.get("userId")));
            }
            return refList;
        }

    }

    /**
     * @param uid  异常
     * @param type
     * @return 角色列表
     * @throws Exception 基类异常
     * @desc 根据当前登录用户查询其可进行分配的角色
     * @author zhangkai
     * @date 2017/2/11
     * @time 09:37
     * @update_user
     * @update_time
     * @update_desc:
     */
    @Override
    public List tree(String uid, String type) throws Exception {
        //当前管理员，只可分配，其拥有的访问角色权限
        String sqlStr = "select distinct r.* from t_bc_role_data r ,t_bc_role_user ru where r.id = ru.r_id "
                + " and r.status = '1' and ru.u_id = ? and ru.r_type=? order by disp_order asc ";
        return this.tBcRoleDataDao.list(sqlStr, uid, type);
    }

    /**
     * @param id   数据角色ID
     * @param type 数据角色类型
     * @return
     * @throws Exception 基类类型
     * @desc 查询分配的权限
     */
    @Override
    public List orgTree(String id, String type,String companyId) throws Exception {
        checkedOrgMap = getCheckOrgMap(id, type);
        //减少判断次数
        if (DEPT_ROLE.equals(type)) {
            return buildOrgChild(companyId);
        }
        return buildUserChild(companyId);
    }


    /**
     * @param pId 上级资源 ID
     * @return List
     * @throws Exception
     * @desc 拼接选择的资源树
     */
    private List buildOrgChild(String pId) throws Exception {

        String sqlStr = "select id,o_name from t_bc_organ where o_p_id=?";

        List<Map<String, Object>> treeP = this.tBcRoleDataDao.list(sqlStr, pId);
        return buildOrgParent(treeP);
    }


    /**
     * @param treeP 节点列表
     * @return List
     * @throws Exception 基类
     * @desc 获取当前节点的子节点，并生成树状结点，结合buildResChild使用
     */
    private List buildOrgParent(List<Map<String, Object>> treeP) throws Exception {
        if (treeP.size() == 0) {
            return treeP;
        }
        List<Map<String, Object>> treeList = new ArrayList<>();
        List<Map<String, Object>> childList;
        for (Map map : treeP) {
            String resId = String.valueOf(map.get("id"));
            childList = buildOrgChild(resId);
            if (childList.size() == 0) {
                //不存在子节点时，判断当前节点是为选中节点
                if (checkedOrgMap.containsKey(resId)) {
                    treeList.add(map);
                }
                continue;
            }
            //存在子节点，增加子节点 返回
            map.put("child", childList);
            treeList.add(map);
        }
        return treeList;
    }

    /**
     * @param pId 上级资源 ID
     * @return List
     * @throws Exception
     * @desc 拼接选择的资源树
     */
    private List buildUserChild(String pId) throws Exception {

        String sqlStr = "select id,o_name from t_bc_organ where o_p_id=?";
        List<Map<String, Object>> treeP = this.tBcRoleDataDao.list(sqlStr, pId);
        return buildUserParent(treeP);
    }

    /**
     * @param treeP 部门列表
     * @return
     * @throws Exception
     * @desc 部门关联用户
     */
    public List buildUserParent(List<Map<String, Object>> treeP) throws Exception {
        if (treeP.size() == 0) {
            return treeP;
        }
        List<Map<String, Object>> treeList = new ArrayList<>();
        List<Map<String, Object>> childList;
        List<Map<String, Object>> userList;
        List<Map<String, Object>> treeUserList;

        for (Map map : treeP) {
            String resId = String.valueOf(map.get("id"));
            childList = buildUserChild(resId);

            //获取当前部门所分配的用户
            userList = getUserChild(resId);
            treeUserList = new ArrayList();
            for (Map userMap : userList) {
                //已分配当前用户
                if (checkedOrgMap.containsKey(String.valueOf(userMap.get("id")))) {
                    treeUserList.add(userMap);
                    continue;
                }
            }
            // 当前用户
            //没有下级部门时，遍历用户，做为下级，否则返回空
            if (childList.size() == 0) {
                //如果有已分配的用户
                if (treeUserList.size() > 0) {
                    map.put("child", treeUserList);
                    treeList.add(map);
                }

            } else {
                childList.addAll(treeUserList);
                //存在下级部门
                map.put("child", childList);
                treeList.add(map);
            }


        }
        return treeList;

    }

    /**
     * @param pId 组织机构ID
     * @return List
     * @throws Exception
     * @desc 获取部门的用户
     */
    private List getUserChild(String pId) throws Exception {

        String sqlStr = "select id,u_name as oName from t_bc_user where o_id = ? and u_status='1' ";
        List<Map<String, Object>> userList = this.tBcRoleDataDao.list(sqlStr, pId);
        return userList;
    }

    /**
     * @param rId  角色 ID
     * @param type 角色类型
     * @return Map
     * @throws Exception
     * @desc 获取当前角色 已分配的组织或用户列表
     */
    private Map<String, String> getCheckOrgMap(String rId, String type) throws Exception {
        String sqlStr = " select org_id,user_id from t_bc_role_data_org where role_type= ? and role_id= ? ";
        List<Map<String, Object>> resList = this.tBcRoleDataDao.list(sqlStr, type, rId);
        Map<String, String> tempMap = new HashMap();
        if (type.equals(DEPT_ROLE)) {
            for (Map map : resList) {
                //部门ID 当做主键
                tempMap.put(String.valueOf(map.get("orgId")), rId);
            }
            return tempMap;
        } else {
            //
            for (Map map : resList) {
                //用户 ID 当做主键
                tempMap.put(String.valueOf(map.get("userId")), rId);
            }
            return tempMap;
        }
    }

    /**
     * @param id       角色主键
     * @param roleType 角色类型，默认为数据角色
     * @param refNodes 要保存的数据
     * @return
     * @throws Exception 异常
     * @desc 保存分配给该角色的权限
     */
    @Override
        public void saveRef(String id, String roleType, List<Map<String, Object>> refNodes) throws Exception {
        List entityList = new ArrayList();
        TBcRoleDataOrg org;
        if (DEPT_ROLE.equals(roleType)) {
            for (Map orgMap : refNodes) {
                //部门权限
                org = new TBcRoleDataOrg();
                org.setRoleType(roleType);
                org.setRoleId(id);
                org.setOrgId(String.valueOf(orgMap.get("id")));
                entityList.add(org);
            }
        } else {
            for (Map orgMap : refNodes) {
                if (USER_TYPE.equals(String.valueOf(orgMap.get("type")).toUpperCase())) {
                    //节点类型为用户
                    org = new TBcRoleDataOrg();
                    org.setRoleType(roleType);
                    org.setRoleId(id);
                    org.setUserId(String.valueOf(orgMap.get("id")));
                    entityList.add(org);
                }

            }
        }
        //删除原有权限节点 //2017-05-10 王帅
        String sql = "delete FROM t_bc_role_data_org where role_id=?";
        this.tBcRoleDataDao.executeSQL(sql, id);
        this.tBcRoleDataDao.saveOrUpdateList(entityList);

    }

    @Override
    public Map findRoleInfoByOIdAndUId(String uid, String oid) throws Exception {
        String sql="SELECT  ro.org_id, ru.u_id,ru.r_id FROM t_bc_role_user ru, t_bc_role_data_org ro WHERE " +
                "ru.r_id=ro.role_id AND ru.u_id = ? and ro.org_id=? group by ro.org_id";
        List<Map<String, Object>> list=this.tBcRoleDataDao.list(sql,uid,oid);
        if(list.size()>0){
            return list.get(0);
        }
        return null;
    }

}
